# load required libraries
library(tidyverse)
library(langcog) # source: https://github.com/langcog/langcog-package
library(psych)
library(lme4)
library(cowplot)
# set theme for ggplots
theme_set(theme_bw())

Data preparation

d_all <- bind_rows(d_us_ad %>% rownames_to_column("subid"), 
                   d_us_ch %>% rownames_to_column("subid"),
                   d_gh_ad %>% rownames_to_column("subid"), 
                   d_gh_ch_fante %>% rownames_to_column("subid"),
                   d_th_ad %>% rownames_to_column("subid"), 
                   d_th_ch %>% rownames_to_column("subid"),
                   d_vt_ad %>% rownames_to_column("subid"), 
                   d_vt_ch %>% rownames_to_column("subid")) %>%
  column_to_rownames("subid")

Shared conceptual structure

Pooling all participants from all sites together into a common factor structure.

Parallel analysis

How many factors to retain?

reten_all_PA <- fa.parallel(d_all, plot = F); reten_all_PA
Parallel analysis suggests that the number of factors =  4  and the number of components =  3 
Call: fa.parallel(x = d_all, plot = F)
Parallel analysis suggests that the number of factors =  4  and the number of components =  3 

 Eigen Values of 
reten_all_par <- reten_all_PA$nfact

What are these factors?

efa_all_par <- fa(d_all, nfactors = reten_all_par, rotate = "varimax",
                  scores = "tenBerge", impute = "median")
efa_all_par_factornames <- c("[other]", "BODILY", 
                             "SOCIAL-EMOTIONAL", "COGNITIVE")
efa_all_par_factornames_short <- c("[other]", "BOD.", 
                                   "SOC.-EMO.", "COG.")
heatmap_fun(efa_all_par, factor_names = efa_all_par_factornames) +
  labs(title = "Factor loadings (data pooled across all samples)")
the condition has length > 1 and only the first element will be usedJoining, by = "capacity"
Joining, by = "factor"

Which capacities are attributed to which targets?

Factor scores

scoresplot_fun(efa_all_par, target = "all",
               factor_names = efa_all_par_factornames) + 
  labs(title = "Factor scores (by sample, factor, and target entity)",
       subtitle = "All targets")
the condition has length > 1 and only the first element will be used

|==============================                    | 61% ~1 s remaining     
|==============================                    | 62% ~1 s remaining     
|================================                  | 64% ~1 s remaining     
|=================================                 | 67% ~1 s remaining     
|==================================                | 70% ~1 s remaining     
|===================================               | 72% ~1 s remaining     
|=====================================             | 75% ~1 s remaining     
|======================================            | 77% ~1 s remaining     
|=======================================           | 79% ~1 s remaining     
|========================================          | 80% ~1 s remaining     
|========================================          | 82% ~1 s remaining     
|=========================================         | 83% ~1 s remaining     
|==========================================        | 85% ~0 s remaining     
|===========================================       | 87% ~0 s remaining     
|============================================      | 89% ~0 s remaining     
|=============================================     | 92% ~0 s remaining     
|==============================================    | 93% ~0 s remaining     
|================================================  | 96% ~0 s remaining     
|================================================= | 98% ~0 s remaining     
Ignoring unknown aesthetics: y

scoresplot_fun(efa_all_par, target = c("ghosts", "God", "children"),
               factor_names = efa_all_par_factornames_short) + 
  labs(title = "Factor scores (by sample, factor, and target entity)",
       subtitle = "Human and 'supernatural' targets only")
the condition has length > 1 and only the first element will be usedthe condition has length > 1 and only the first element will be usedthe condition has length > 1 and only the first element will be usedthe condition has length > 1 and only the first element will be usedIgnoring unknown aesthetics: y

itemsplot_fun(efa_all_par, target = c("ghosts", "God", "children")) +
  labs(title = "Parallel Analysis")
the condition has length > 1 and only the first element will be usedthe condition has length > 1 and only the first element will be usedthe condition has length > 1 and only the first element will be usedJoining, by = "capacity"

|======================                            | 45% ~2 s remaining     
|=======================                           | 46% ~2 s remaining     
|=======================                           | 46% ~2 s remaining     
|=======================                           | 47% ~2 s remaining     
|=======================                           | 48% ~2 s remaining     
|========================                          | 48% ~2 s remaining     
|========================                          | 49% ~2 s remaining     
|========================                          | 50% ~2 s remaining     
|=========================                         | 50% ~2 s remaining     
|=========================                         | 51% ~2 s remaining     
|=========================                         | 52% ~2 s remaining     
|==========================                        | 52% ~2 s remaining     
|==========================                        | 53% ~2 s remaining     
|==========================                        | 53% ~2 s remaining     
|==========================                        | 54% ~2 s remaining     
|===========================                       | 54% ~2 s remaining     
|===========================                       | 55% ~2 s remaining     
|===========================                       | 56% ~2 s remaining     
|============================                      | 56% ~2 s remaining     
|============================                      | 57% ~2 s remaining     
|============================                      | 58% ~2 s remaining     
|=============================                     | 58% ~2 s remaining     
|=============================                     | 59% ~2 s remaining     
|=============================                     | 60% ~2 s remaining     
|==============================                    | 60% ~2 s remaining     
|==============================                    | 61% ~2 s remaining     
|==============================                    | 62% ~2 s remaining     
|===============================                   | 62% ~2 s remaining     
|===============================                   | 63% ~2 s remaining     
|================================                  | 64% ~2 s remaining     
|================================                  | 64% ~2 s remaining     
|================================                  | 65% ~2 s remaining     
|================================                  | 66% ~2 s remaining     
|=================================                 | 66% ~2 s remaining     
|=================================                 | 67% ~2 s remaining     
|=================================                 | 68% ~2 s remaining     
|==================================                | 68% ~2 s remaining     
|==================================                | 69% ~2 s remaining     
|==================================                | 70% ~2 s remaining     
|===================================               | 70% ~2 s remaining     
|===================================               | 71% ~2 s remaining     
|===================================               | 72% ~2 s remaining     
|====================================              | 73% ~2 s remaining     
|====================================              | 73% ~2 s remaining     
|=====================================             | 74% ~2 s remaining     
|=====================================             | 75% ~2 s remaining     
|=====================================             | 76% ~2 s remaining     
|======================================            | 76% ~2 s remaining     
|======================================            | 77% ~1 s remaining     
|======================================            | 78% ~1 s remaining     
|=======================================           | 78% ~1 s remaining     
|=======================================           | 79% ~1 s remaining     
|========================================          | 80% ~1 s remaining     
|========================================          | 81% ~1 s remaining     
|========================================          | 81% ~1 s remaining     
|=========================================         | 82% ~1 s remaining     
|=========================================         | 82% ~1 s remaining     
|=========================================         | 83% ~1 s remaining     
|=========================================         | 83% ~1 s remaining     
|==========================================        | 84% ~1 s remaining     
|==========================================        | 85% ~1 s remaining     
|==========================================        | 85% ~1 s remaining     
|==========================================        | 86% ~1 s remaining     
|===========================================       | 86% ~1 s remaining     
|===========================================       | 87% ~1 s remaining     
|============================================      | 88% ~1 s remaining     
|============================================      | 89% ~1 s remaining     
|============================================      | 90% ~1 s remaining     
|=============================================     | 91% ~1 s remaining     
|=============================================     | 91% ~1 s remaining     
|==============================================    | 92% ~1 s remaining     
|==============================================    | 93% ~0 s remaining     
|==============================================    | 93% ~0 s remaining     
|===============================================   | 94% ~0 s remaining     
|===============================================   | 95% ~0 s remaining     
|===============================================   | 95% ~0 s remaining     
|================================================  | 96% ~0 s remaining     
|================================================  | 97% ~0 s remaining     
|================================================  | 98% ~0 s remaining     
|================================================= | 98% ~0 s remaining     
|================================================= | 99% ~0 s remaining     
|==================================================|100% ~0 s remaining     
Joining, by = c("factor", "capacity", "order")

Summary scores

factors_par <- efa_all_par$loadings[] %>%
  data.frame() %>%
  rownames_to_column("capacity") %>%
  gather(factor, loading, -capacity) %>%
  group_by(capacity) %>%
  top_n(1, loading) %>%
  ungroup() %>%
  arrange(factor, desc(loading)) %>%
  mutate(order = 1:nrow(.),
         factor = factor(factor,
                         levels = paste0("MR", 1:efa_all_par$factors),
                         labels = efa_all_par_factornames),
         factor = factor(as.character(factor)))
# factors_par_howmany <- factors_par %>%
#   count(factor)
# factors_par_howmany <- min(factors_par_howmany$n)
factors_par_howmany <- 6
factors_par_culled <- factors_par %>%
  group_by(factor) %>%
  top_n(factors_par_howmany, loading) %>%
  ungroup() %>%
  arrange(factor, desc(loading)) %>%
  mutate(order = 1:nrow(.))
scores_par_prelim <- d_all %>%
  rownames_to_column("site_age_subid_target_entity") %>%
  gather(capacity, response, -site_age_subid_target_entity) %>%
  mutate(site = gsub("_.*$", "", site_age_subid_target_entity),
         age = gsub("_.*$", "", gsub("^.._", "", site_age_subid_target_entity)),
         subid = gsub("_target.*$", "", site_age_subid_target_entity),
         target = gsub("^.*target_", "", site_age_subid_target_entity)) %>%
  mutate(target = case_when(target == "pigs" ~ NA_character_,
                            target == "NA" ~ NA_character_,
                            target == "crickets" ~ "beetles",
                            TRUE ~ target)) %>%
  mutate(site = factor(site, levels = c("us", "gh", "th", "ch", "vt"),
                       labels = c("US", "Ghana", "Thailand", 
                                  "China", "Vanuatu")),
         age = factor(age, levels = c("ad", "ch"),
                      labels = c("adults", "children")),
         target = factor(target,
                         levels = c("rocks", "flowers", "cell phones", 
                                    "beetles", "chickens", "mice", 
                                    "dogs", "children", "ghosts", "God"))) %>%
  select(-site_age_subid_target_entity) %>%
  full_join(factors_par_culled) %>%
  # full_join(factors_par) %>%
  filter(!is.na(target), !is.na(factor)) %>%
  distinct()
Joining, by = "capacity"
scores_par <- scores_par_prelim %>%
  group_by(site, age, subid, target, factor) %>%
  summarise(score = mean(response, na.rm = T)) %>%
  ungroup()
scores_par_mb <- scores_par %>% 
  group_by(site, age, target, factor) %>%
  multi_boot_standard(col = "score", na.rm = T) %>%
  ungroup()

|====================================              | 73% ~1 s remaining     
|=====================================             | 75% ~1 s remaining     
|======================================            | 77% ~1 s remaining     
|=======================================           | 79% ~1 s remaining     
|========================================          | 80% ~1 s remaining     
|=========================================         | 82% ~1 s remaining     
|==========================================        | 84% ~0 s remaining     
|===========================================       | 86% ~0 s remaining     
|===========================================       | 88% ~0 s remaining     
|============================================      | 89% ~0 s remaining     
|=============================================     | 91% ~0 s remaining     
|==============================================    | 92% ~0 s remaining     
|==============================================    | 93% ~0 s remaining     
|===============================================   | 95% ~0 s remaining     
|================================================  | 98% ~0 s remaining     
|================================================= | 99% ~0 s remaining     
# calculate reliability
scores_par_prelim_wide <- scores_par_prelim %>%
  full_join(factors_par_culled) %>%
  filter(!is.na(factor), !is.na(subid)) %>% 
  arrange(factor, desc(loading)) %>%
  select(subid, capacity, response) %>%
  spread(capacity, response) %>%
  select(subid, factors_par_culled$capacity) %>%
  column_to_rownames("subid")
Joining, by = c("capacity", "factor", "loading", "order")
# BODILY
paste(names(scores_par_prelim_wide[1:6]), collapse = ", ")
[1] "get hungry, feel pain, feel sick, like when you feel like you might vomit, feel tired, feel scared, smell things"
alpha(scores_par_prelim_wide[1:6])$total
# "COGNITIVE"
paste(names(scores_par_prelim_wide[7:12]), collapse = ", ")
[1] "remember things, figure out how to do things, choose what to do, think about things, sense when things are far away, hear things"
alpha(scores_par_prelim_wide[7:12])$total
# "SOCIAL-EMOTIONAL"
paste(names(scores_par_prelim_wide[13:18]), collapse = ", ")
[1] "get hurt feelings, feel guilty, feel sad, feel proud, feel shy, feel love"
alpha(scores_par_prelim_wide[13:18])$total
ggplot(scores_par, aes(x = target, y = score, color = factor)) +
  facet_grid(cols = vars(site, age), rows = vars(factor)) +
  geom_jitter(height = 0.02, width = 0.2, alpha = 0.2, show.legend = F) +
  geom_pointrange(data = scores_par_mb,
                  aes(y = mean, ymin = ci_lower, ymax = ci_upper),
                  fatten = 2, color = "black") +
  scale_color_brewer(palette = "Set1") +
  theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1))

ggplot(scores_par %>%
         mutate(factor_short = recode_factor(
           factor,
           "BODILY" = "BOD.",
           "COGNITIVE" = "COG.",
           "SOCIAL-EMOTIONAL" = "SOC.-EMO.")) %>%
         filter(target %in% c("children", "ghosts", "God")), 
       aes(x = target, y = score, color = factor_short)) +
  facet_grid(cols = vars(site, age), rows = vars(factor_short)) +
  geom_jitter(height = 0.02, width = 0.2, alpha = 0.25, show.legend = F) +
  geom_pointrange(data = scores_par_mb %>%
                    mutate(factor_short = recode_factor(
                      factor,
                      "BODILY" = "BOD.",
                      "COGNITIVE" = "COG.",
                      "SOCIAL-EMOTIONAL" = "SOC.-EMO.")) %>%
                    filter(target %in% c("children", "ghosts", "God")),
                  aes(y = mean, ymin = ci_lower, ymax = ci_upper),
                  fatten = 2, color = "black") +
  scale_color_brewer(palette = "Set1") +
  theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1))

Minimizing BIC

How many factors to retain?

reten_all_BIC <- VSS(d_all, plot = F); reten_all_BIC

Very Simple Structure
Call: vss(x = x, n = n, rotate = rotate, diagonal = diagonal, fm = fm, 
    n.obs = n.obs, plot = plot, title = title, use = use, cor = cor)
VSS complexity 1 achieves a maximimum of 0.91  with  1  factors
VSS complexity 2 achieves a maximimum of 0.94  with  2  factors

The Velicer MAP achieves a minimum of 0.01  with  3  factors 
BIC achieves a minimum of  -616.49  with  4  factors
Sample Size adjusted BIC achieves a minimum of  -171.4  with  7  factors

Statistics by number of factors 
reten_all_bic <- data.frame(reten_all_BIC$vss.stats %>% rownames_to_column("nfact") %>% top_n(-1, BIC))$nfact %>% as.numeric()

Preset criteria

How many factors to retain?

reten_all_k <- reten_fun(d_all, rot_type = "varimax"); reten_all_k
[1] 2

What are these factors?

efa_all_k <- fa(d_all, nfactors = reten_all_k, rotate = "varimax",
                scores = "tenBerge", impute = "median")
heatmap_fun(efa_all_k) + 
  labs(title = "Preset criteria (Weisman et al., 2017)")
Joining, by = "capacity"
Joining, by = "factor"

Which capacities are attributed to which targets?

scoresplot_fun(efa_all_k, target = "all") + 
  labs(title = "Preset criteria (Weisman et al., 2017)")
Ignoring unknown aesthetics: y

scoresplot_fun(efa_all_k, target = c("ghosts", "God", "children")) + 
  labs(title = "Preset criteria (Weisman et al., 2017)")
the condition has length > 1 and only the first element will be usedthe condition has length > 1 and only the first element will be usedthe condition has length > 1 and only the first element will be usedIgnoring unknown aesthetics: y

itemsplot_fun(efa_all_k, target = c("ghosts", "God", "children")) + 
  labs(title = "Preset criteria (Weisman et al., 2017)")
the condition has length > 1 and only the first element will be usedthe condition has length > 1 and only the first element will be usedthe condition has length > 1 and only the first element will be usedJoining, by = "capacity"

|===============                                   | 31% ~4 s remaining     
|================                                  | 32% ~4 s remaining     
|================                                  | 33% ~4 s remaining     
|================                                  | 34% ~4 s remaining     
|=================                                 | 35% ~4 s remaining     
|=================                                 | 35% ~4 s remaining     
|==================                                | 36% ~4 s remaining     
|==================                                | 38% ~4 s remaining     
|===================                               | 39% ~4 s remaining     
|===================                               | 39% ~4 s remaining     
|===================                               | 40% ~4 s remaining     
|====================                              | 40% ~4 s remaining     
|====================                              | 41% ~4 s remaining     
|====================                              | 42% ~4 s remaining     
|=====================                             | 43% ~4 s remaining     
|=====================                             | 44% ~4 s remaining     
|======================                            | 45% ~4 s remaining     
|======================                            | 45% ~4 s remaining     
|======================                            | 46% ~4 s remaining     
|=======================                           | 46% ~4 s remaining     
|=======================                           | 47% ~3 s remaining     
|========================                          | 48% ~3 s remaining     
|========================                          | 49% ~3 s remaining     
|========================                          | 49% ~3 s remaining     
|=========================                         | 50% ~3 s remaining     
|=========================                         | 51% ~3 s remaining     
|=========================                         | 52% ~3 s remaining     
|==========================                        | 52% ~3 s remaining     
|==========================                        | 53% ~3 s remaining     
|==========================                        | 54% ~3 s remaining     
|===========================                       | 55% ~3 s remaining     
|===========================                       | 55% ~3 s remaining     
|===========================                       | 55% ~3 s remaining     
|============================                      | 56% ~3 s remaining     
|============================                      | 57% ~3 s remaining     
|============================                      | 58% ~3 s remaining     
|=============================                     | 59% ~3 s remaining     
|=============================                     | 59% ~3 s remaining     
|=============================                     | 60% ~3 s remaining     
|==============================                    | 60% ~3 s remaining     
|==============================                    | 61% ~3 s remaining     
|===============================                   | 62% ~3 s remaining     
|===============================                   | 63% ~3 s remaining     
|===============================                   | 63% ~3 s remaining     
|================================                  | 64% ~2 s remaining     
|================================                  | 65% ~2 s remaining     
|================================                  | 66% ~2 s remaining     
|=================================                 | 66% ~2 s remaining     
|=================================                 | 67% ~2 s remaining     
|=================================                 | 68% ~2 s remaining     
|==================================                | 68% ~2 s remaining     
|==================================                | 69% ~2 s remaining     
|===================================               | 70% ~2 s remaining     
|===================================               | 71% ~2 s remaining     
|====================================              | 73% ~2 s remaining     
|====================================              | 74% ~2 s remaining     
|=====================================             | 74% ~2 s remaining     
|=====================================             | 75% ~2 s remaining     
|=====================================             | 76% ~2 s remaining     
|======================================            | 77% ~2 s remaining     
|======================================            | 78% ~2 s remaining     
|=======================================           | 78% ~1 s remaining     
|=======================================           | 79% ~1 s remaining     
|=======================================           | 80% ~1 s remaining     
|========================================          | 80% ~1 s remaining     
|========================================          | 81% ~1 s remaining     
|=========================================         | 82% ~1 s remaining     
|=========================================         | 83% ~1 s remaining     
|=========================================         | 84% ~1 s remaining     
|==========================================        | 84% ~1 s remaining     
|==========================================        | 84% ~1 s remaining     
|==========================================        | 85% ~1 s remaining     
|==========================================        | 86% ~1 s remaining     
|===========================================       | 87% ~1 s remaining     
|===========================================       | 88% ~1 s remaining     
|============================================      | 88% ~1 s remaining     
|============================================      | 89% ~1 s remaining     
|============================================      | 90% ~1 s remaining     
|=============================================     | 91% ~1 s remaining     
|=============================================     | 91% ~1 s remaining     
|=============================================     | 92% ~1 s remaining     
|==============================================    | 93% ~1 s remaining     
|==============================================    | 94% ~0 s remaining     
|===============================================   | 94% ~0 s remaining     
|===============================================   | 95% ~0 s remaining     
|===============================================   | 95% ~0 s remaining     
|================================================  | 96% ~0 s remaining     
|================================================  | 97% ~0 s remaining     
|================================================  | 98% ~0 s remaining     
|================================================= | 98% ~0 s remaining     
|================================================= | 99% ~0 s remaining     
|================================================= |100% ~0 s remaining     
|==================================================|100% ~0 s remaining     
Joining, by = c("factor", "capacity", "order")

3 factors

What are these factors?

efa_all_3 <- fa(d_all, nfactors = 3, rotate = "varimax",
                scores = "tenBerge", impute = "median")
efa_all_3_factornames <- c("BODILY", "COGNITIVE", "SOCIAL-EMOTIONAL")
efa_all_3_factornames_short <- c("BOD.", "COG.", "SOC.-EMO.")
heatmap_fun(efa_all_3, factor_names = efa_all_3_factornames) + 
  labs(x = "Shared concpetual structure") +
  theme(axis.title.x = element_text(hjust = 0))
the condition has length > 1 and only the first element will be usedJoining, by = "capacity"
Joining, by = "factor"

# labs(title = "Preset criteria (Weisman et al., 2017)")

Which capacities are attributed to which targets?

scoresplot_fun(efa_all_3, target = "all", highlight = "supernatural",
               factor_names = efa_all_3_factornames) +
  # scale_fill_manual(values = c("#e41a1c", "#4daf4a", "#377eb8")) +
  theme(axis.text.x = element_text(angle = 90, hjust = 1, vjust = 1,
                                   color = c(rep("black", 8),
                                             rep("#984ea3", 2)),
                                   face = c(rep("plain", 8),
                                            rep("bold", 2))))
the condition has length > 1 and only the first element will be used

|==============================================    | 93% ~0 s remaining     
|===============================================   | 95% ~0 s remaining     
|================================================= | 98% ~0 s remaining     
Ignoring unknown aesthetics: y

scoresplot_fun(efa_all_3, target = c("ghosts", "God", "children"), 
               factor_names = efa_all_3_factornames_short) + 
  labs(title = "Preset criteria (Weisman et al., 2017)")
the condition has length > 1 and only the first element will be usedthe condition has length > 1 and only the first element will be usedthe condition has length > 1 and only the first element will be usedthe condition has length > 1 and only the first element will be usedIgnoring unknown aesthetics: y

itemsplot_fun(efa_all_3, target = c("ghosts", "God", "children"),
              factor_names = efa_all_3_factornames) + 
  labs(title = "Preset criteria (Weisman et al., 2017)")
the condition has length > 1 and only the first element will be usedthe condition has length > 1 and only the first element will be usedthe condition has length > 1 and only the first element will be usedJoining, by = "capacity"
the condition has length > 1 and only the first element will be used

|===========================                       | 55% ~2 s remaining     
|============================                      | 56% ~2 s remaining     
|============================                      | 57% ~2 s remaining     
|============================                      | 58% ~2 s remaining     
|=============================                     | 59% ~2 s remaining     
|=============================                     | 59% ~2 s remaining     
|=============================                     | 59% ~2 s remaining     
|=============================                     | 60% ~2 s remaining     
|==============================                    | 61% ~2 s remaining     
|===============================                   | 62% ~2 s remaining     
|================================                  | 64% ~1 s remaining     
|================================                  | 65% ~1 s remaining     
|================================                  | 66% ~1 s remaining     
|=================================                 | 67% ~1 s remaining     
|==================================                | 68% ~1 s remaining     
|==================================                | 69% ~1 s remaining     
|===================================               | 70% ~1 s remaining     
|===================================               | 71% ~1 s remaining     
|===================================               | 72% ~1 s remaining     
|====================================              | 72% ~1 s remaining     
|====================================              | 73% ~1 s remaining     
|=====================================             | 74% ~1 s remaining     
|=====================================             | 75% ~1 s remaining     
|======================================            | 76% ~1 s remaining     
|======================================            | 78% ~1 s remaining     
|=======================================           | 79% ~1 s remaining     
|========================================          | 80% ~1 s remaining     
|========================================          | 81% ~1 s remaining     
|=========================================         | 82% ~1 s remaining     
|=========================================         | 83% ~1 s remaining     
|==========================================        | 84% ~1 s remaining     
|==========================================        | 85% ~1 s remaining     
|==========================================        | 86% ~1 s remaining     
|===========================================       | 87% ~1 s remaining     
|===========================================       | 87% ~1 s remaining     
|===========================================       | 88% ~1 s remaining     
|============================================      | 88% ~1 s remaining     
|============================================      | 89% ~1 s remaining     
|============================================      | 90% ~0 s remaining     
|=============================================     | 91% ~0 s remaining     
|==============================================    | 92% ~0 s remaining     
|==============================================    | 93% ~0 s remaining     
|===============================================   | 94% ~0 s remaining     
|===============================================   | 95% ~0 s remaining     
|================================================  | 96% ~0 s remaining     
|================================================  | 97% ~0 s remaining     
|================================================= | 98% ~0 s remaining     
|================================================= | 99% ~0 s remaining     
|================================================= |100% ~0 s remaining     
Joining, by = c("factor", "capacity", "order")

Comparing conceptual structures

4 factors

We’ll extract 4 factors from all samples, to keep things simple.

efa_us_ad_4 <- fa(d_us_ad, nfactors = 4, rotate = "varimax")
efa_us_ch_4 <- fa(d_us_ch, nfactors = 4, rotate = "varimax")
efa_gh_ad_4 <- fa(d_gh_ad, nfactors = 4, rotate = "varimax")
efa_gh_ch_4 <- fa(d_gh_ch_fante, nfactors = 4, rotate = "varimax")
efa_th_ad_4 <- fa(d_th_ad, nfactors = 4, rotate = "varimax")
efa_th_ch_4 <- fa(d_th_ch, nfactors = 4, rotate = "varimax")
efa_vt_ad_4 <- fa(d_vt_ad, nfactors = 4, rotate = "varimax")
efa_vt_ch_4 <- fa(d_vt_ch, nfactors = 4, rotate = "varimax")
plot_us_ad_4 <- heatmap_fun(efa_us_ad_4) + 
  guides(fill = "none") + 
  labs(x = "US: adults") +
  theme(axis.title.x = element_text(hjust = 0))
Joining, by = "capacity"
Joining, by = "factor"
plot_us_ch_4 <- heatmap_fun(efa_us_ch_4) + 
  guides(fill = "none") + 
  labs(x = "US: children") +
  theme(axis.title.x = element_text(hjust = 0))
Joining, by = "capacity"
Joining, by = "factor"
plot_gh_ad_4 <- heatmap_fun(efa_gh_ad_4) + 
  guides(fill = "none") + 
  labs(x = "Ghana: adults") +
  theme(axis.title.x = element_text(hjust = 0))
Joining, by = "capacity"
Joining, by = "factor"
plot_gh_ch_4 <- heatmap_fun(efa_gh_ch_4) + 
  guides(fill = "none") + 
  labs(x = "Ghana: children") +
  theme(axis.title.x = element_text(hjust = 0))
Joining, by = "capacity"
Joining, by = "factor"
plot_th_ad_4 <- heatmap_fun(efa_th_ad_4) + 
  guides(fill = "none") + 
  labs(x = "Thailand: adults") +
  theme(axis.title.x = element_text(hjust = 0))
Joining, by = "capacity"
Joining, by = "factor"
plot_th_ch_4 <- heatmap_fun(efa_th_ch_4) + 
  guides(fill = "none") + 
  labs(x = "Thailand: children") +
  theme(axis.title.x = element_text(hjust = 0))
Joining, by = "capacity"
Joining, by = "factor"
plot_vt_ad_4 <- heatmap_fun(efa_vt_ad_4) + 
  guides(fill = "none") + 
  labs(x = "Vanuatu: adults") +
  theme(axis.title.x = element_text(hjust = 0))
Joining, by = "capacity"
Joining, by = "factor"
plot_vt_ch_4 <- heatmap_fun(efa_vt_ch_4) + 
  guides(fill = "none") + 
  labs(x = "Vanuatu: children") +
  theme(axis.title.x = element_text(hjust = 0))
Joining, by = "capacity"
Joining, by = "factor"
plot_grid(plot_us_ad_4, plot_us_ch_4, 
          plot_gh_ad_4, plot_gh_ch_4, 
          plot_th_ad_4, plot_th_ch_4, 
          plot_vt_ad_4, plot_vt_ch_4, 
          ncol = 2, labels = "AUTO")

3 factors

We’ll extract 3 factors from all samples, to keep things simple.

efa_us_ad_3 <- fa(d_us_ad, nfactors = 3, rotate = "varimax")
efa_us_ch_3 <- fa(d_us_ch, nfactors = 3, rotate = "varimax")
efa_gh_ad_3 <- fa(d_gh_ad, nfactors = 3, rotate = "varimax")
efa_gh_ch_3 <- fa(d_gh_ch_fante, nfactors = 3, rotate = "varimax")
efa_th_ad_3 <- fa(d_th_ad, nfactors = 3, rotate = "varimax")
efa_th_ch_3 <- fa(d_th_ch, nfactors = 3, rotate = "varimax")
efa_vt_ad_3 <- fa(d_vt_ad, nfactors = 3, rotate = "varimax")
efa_vt_ch_3 <- fa(d_vt_ch, nfactors = 3, rotate = "varimax")
plot_us_ad_3 <- heatmap_fun(efa_us_ad_3) + 
  guides(fill = "none") + 
  labs(x = "US: adults") +
  theme(axis.title.x = element_text(hjust = 0))
Joining, by = "capacity"
Joining, by = "factor"
plot_us_ch_3 <- heatmap_fun(efa_us_ch_3) + 
  guides(fill = "none") + 
  labs(x = "US: children") +
  theme(axis.title.x = element_text(hjust = 0))
Joining, by = "capacity"
Joining, by = "factor"
plot_gh_ad_3 <- heatmap_fun(efa_gh_ad_3) + 
  guides(fill = "none") + 
  labs(x = "Ghana: adults") +
  theme(axis.title.x = element_text(hjust = 0))
Joining, by = "capacity"
Joining, by = "factor"
plot_gh_ch_3 <- heatmap_fun(efa_gh_ch_3) + 
  guides(fill = "none") + 
  labs(x = "Ghana: children") +
  theme(axis.title.x = element_text(hjust = 0))
Joining, by = "capacity"
Joining, by = "factor"
plot_th_ad_3 <- heatmap_fun(efa_th_ad_3) + 
  guides(fill = "none") + 
  labs(x = "Thailand: adults") +
  theme(axis.title.x = element_text(hjust = 0))
Joining, by = "capacity"
Joining, by = "factor"
plot_th_ch_3 <- heatmap_fun(efa_th_ch_3) + 
  guides(fill = "none") + 
  labs(x = "Thailand: children") +
  theme(axis.title.x = element_text(hjust = 0))
Joining, by = "capacity"
Joining, by = "factor"
plot_vt_ad_3 <- heatmap_fun(efa_vt_ad_3) + 
  guides(fill = "none") + 
  labs(x = "Vanuatu: adults") +
  theme(axis.title.x = element_text(hjust = 0))
Joining, by = "capacity"
Joining, by = "factor"
plot_vt_ch_3 <- heatmap_fun(efa_vt_ch_3) + 
  guides(fill = "none") + 
  labs(x = "Vanuatu: children") +
  theme(axis.title.x = element_text(hjust = 0))
Joining, by = "capacity"
Joining, by = "factor"
plot_grid(plot_us_ad_3, plot_us_ch_3, 
          plot_gh_ad_3, plot_gh_ch_3, 
          plot_th_ad_3, plot_th_ch_3, 
          plot_vt_ad_3, plot_vt_ch_3, 
          ncol = 2, labels = "AUTO")

Counts

paste("US adults:", nrow(d_us_ad))
[1] "US adults: 127"
paste("US children:", nrow(d_us_ch))
[1] "US children: 117"
paste("GH adults:", nrow(d_gh_ad))
[1] "GH adults: 150"
paste("GH children:", nrow(d_gh_ch))
[1] "GH children: 149"
paste("TH adults:", nrow(d_th_ad))
[1] "TH adults: 150"
paste("TH children:", nrow(d_th_ch))
[1] "TH children: 152"
paste("VT adults:", nrow(d_vt_ad))
[1] "VT adults: 164"
paste("VT children:", nrow(d_vt_ch))
[1] "VT children: 169"
paste("Non-US:", sum(nrow(d_gh_ad), nrow(d_gh_ch),
                     nrow(d_th_ad), nrow(d_th_ch),
                     nrow(d_vt_ad), nrow(d_vt_ch)))
[1] "Non-US: 934"
paste0("Adults: n = ", min(nrow(d_us_ad), nrow(d_gh_ad), nrow(d_th_ad), nrow(d_vt_ad)), "-", max(nrow(d_us_ad), nrow(d_gh_ad), nrow(d_th_ad), nrow(d_vt_ad)), "; total N = ",  sum(nrow(d_us_ad), nrow(d_gh_ad), nrow(d_th_ad), nrow(d_vt_ad)))
[1] "Adults: n = 127-164; total N = 591"
paste0("Children: n = ", min(nrow(d_us_ch), nrow(d_gh_ch), nrow(d_th_ch), nrow(d_vt_ch)), "-", max(nrow(d_us_ch), nrow(d_gh_ch), nrow(d_th_ch), nrow(d_vt_ch)), "; total N = ",  sum(nrow(d_us_ch), nrow(d_gh_ch), nrow(d_th_ch), nrow(d_vt_ch)))
[1] "Children: n = 117-169; total N = 587"
d_all %>%
  rownames_to_column("site_age_subid_target_character") %>%
  mutate(site_age_subid_target_character = gsub("cell phones", "cellphones", site_age_subid_target_character)) %>%
  separate(site_age_subid_target_character, into = c("site", "age", "subid", "target", "character")) %>%
  count(site, age, character) %>%
  spread(character, n)
d_all %>%
  rownames_to_column("site_age_subid_target_character") %>%
  mutate(site_age_subid_target_character = gsub("cell phones", "cellphones", site_age_subid_target_character)) %>%
  separate(site_age_subid_target_character, into = c("site", "age", "subid", "target", "character")) %>%
  filter(is.na(character) | character == "NA")
LS0tCnRpdGxlOiAiU1JDRCAyMDE5IFN5bXBvc2l1bTogUmVsaWdpb3VzICYgbWV0YXBoeXNpY2FsIGNvbmNlcHRzIChTcmluaXZhc2FuKSIKb3V0cHV0OiAKICBodG1sX25vdGVib29rOgogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6IHRydWUKLS0tCgpgYGB7ciBnbG9iYWxfb3B0aW9ucywgaW5jbHVkZSA9IEZ9CmtuaXRyOjpvcHRzX2NodW5rJHNldChmaWcud2lkdGggPSAzLCBmaWcuYXNwID0gMC42NykKYGBgCgpgYGB7cn0KIyBsb2FkIHJlcXVpcmVkIGxpYnJhcmllcwpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShsYW5nY29nKSAjIHNvdXJjZTogaHR0cHM6Ly9naXRodWIuY29tL2xhbmdjb2cvbGFuZ2NvZy1wYWNrYWdlCmxpYnJhcnkocHN5Y2gpCmxpYnJhcnkobG1lNCkKbGlicmFyeShjb3dwbG90KQoKIyBzZXQgdGhlbWUgZm9yIGdncGxvdHMKdGhlbWVfc2V0KHRoZW1lX2J3KCkpCmBgYAoKYGBge3IsIGluY2x1ZGUgPSBGfQpzb3VyY2UoIi4vc2NyaXB0cy9tYXhfZmFjdG9yc19lZmEuUiIpCnNvdXJjZSgiLi9zY3JpcHRzL3Bsb3RfZnVuX2JlZXRsZXMuUiIpCnNvdXJjZSgiLi9zY3JpcHRzL3JldGVuX2Z1bi5SIikKc291cmNlKCIuL3NjcmlwdHMvY2xlYW5fZnVuLlIiKQpgYGAKCiMgRGF0YSBwcmVwYXJhdGlvbgoKYGBge3IsIGluY2x1ZGUgPSBGfQpxdWVzdGlvbl9rZXkgPC0gcmVhZC5jc3YoIi9Vc2Vycy9rd2Vpc21hbi9Eb2N1bWVudHMvUmVzZWFyY2ggKFN0YW5mb3JkKS9Qcm9qZWN0cy9UZW1wbGV0b24gR3JhbnQvREVWRUxPUE1FTlRBTCBUQVNLUy9iZWV0bGVzOmRpbWtpZDpmYWN0b3JzL2Rlc2lnbi9iZWV0bGVzIGNiLmNzdiIpCmBgYAoKYGBge3IsIGluY2x1ZGUgPSBGLCB3YXJuaW5nID0gRkFMU0V9CiMjIFVTIGFkdWx0cwpkX3VzX2FkIDwtIHJlYWQuY3N2KCIvVXNlcnMva3dlaXNtYW4vRGVza3RvcC9URU1QL1RFTVBfVVMvYmVldGxlc191c19hZHVsdHNfdGlkeV8yMDE5LTAyLTIxLmNzdiIpICU+JSBjbGVhbl9mdW4oa2V5ID0gcXVlc3Rpb25fa2V5LCBleF9hZGRzdWIgPSBULCBzaXRlID0gInVzIiwgYWdlID0gImFkIikKIyMgVVMgY2hpbGRyZW4KZF91c19jaCA8LSByZWFkLmNzdigiL1VzZXJzL2t3ZWlzbWFuL0Rlc2t0b3AvVEVNUC9URU1QX1VTL2JlZXRsZXNfdXNfY2hpbGRyZW5fdGlkeV8yMDE5LTAzLTE5LmNzdiIpICU+JSBjbGVhbl9mdW4oa2V5ID0gcXVlc3Rpb25fa2V5LCBleF9hZGRzdWIgPSBULCBzaXRlID0gInVzIiwgYWdlID0gImNoIikKCiMjIEdIIGFkdWx0cwpkX2doX2FkIDwtIHJlYWQuY3N2KCIvVXNlcnMva3dlaXNtYW4vRGVza3RvcC9URU1QL1RFTVBfR0hBTkFfMjAxOC9iZWV0bGVzX2doYW5hX2FkdWx0c190aWR5XzIwMTgtMDgtMTIuY3N2IikgJT4lIGNsZWFuX2Z1bihrZXkgPSBxdWVzdGlvbl9rZXksIGV4X2FkZHN1YiA9IFQsIHNpdGUgPSAiZ2giLCBhZ2UgPSAiYWQiKQojIyBHSCBjaGlsZHJlbgpkX2doX2NoIDwtIHJlYWQuY3N2KCIvVXNlcnMva3dlaXNtYW4vRGVza3RvcC9URU1QL1RFTVBfR0hBTkEvYmVldGxlc19naGFuYV90aWR5XzIwMTctMDctMTIuY3N2IikgJT4lIGNsZWFuX2Z1bihrZXkgPSBxdWVzdGlvbl9rZXksIGV4X2FkZHN1YiA9IFQsIHNpdGUgPSAiZ2giLCBhZ2UgPSAiY2giKQpkX2doX2NoX2ZhbnRlIDwtIHJlYWQuY3N2KCIvVXNlcnMva3dlaXNtYW4vRGVza3RvcC9URU1QL1RFTVBfR0hBTkFfMjAxOC9iZWV0bGVzX2doYW5hX2ZhbnRlX2NoaWxkcmVuX3RpZHlfMjAxOC0wNy0xOS5jc3YiKVstMV0gJT4lIAogIHJlbmFtZShzdWJudW0gPSBzdWJpZCkgJT4lIAogIGZpbHRlcihncmVwbCgiZmFudGUiLCB0b2xvd2VyKGxhbmd1YWdlX2hvbWUpKSB8IGdyZXBsKCJ0d2kiLCB0b2xvd2VyKGxhbmd1YWdlX2hvbWUpKSkgJT4lCiAgY2xlYW5fZnVuKGtleSA9IHF1ZXN0aW9uX2tleSwgZXhfYWRkc3ViID0gVCwgc2l0ZSA9ICJnaCIsIGFnZSA9ICJjaCIpCgojIyBDSCBhZHVsdHM6IE5PVCBZRVQgUlVOCiMjIENIIGNoaWxkcmVuOiBOT1QgWUVUIFJVTgoKIyMgVEggYWR1bHRzCmRfdGhfYWQgPC0gcmVhZC5jc3YoIi9Vc2Vycy9rd2Vpc21hbi9EZXNrdG9wL1RFTVAvVEVNUF9USEFJTEFORC9iZWV0bGVzX3RoYWlsYW5kX2FkdWx0c190aWR5XzIwMTgtMDUtMDkuY3N2IikgJT4lIGNsZWFuX2Z1bihrZXkgPSBxdWVzdGlvbl9rZXksIGV4X2FkZHN1YiA9IFQsIHNpdGUgPSAidGgiLCBhZ2UgPSAiYWQiKQojIyBUSCBjaGlsZHJlbgpkX3RoX2NoIDwtIHJlYWQuY3N2KCIvVXNlcnMva3dlaXNtYW4vRGVza3RvcC9URU1QL1RFTVBfVEhBSUxBTkQvYmVldGxlc190aGFpbGFuZF9jaGlsZHJlbl90aWR5XzIwMTgtMDUtMDkuY3N2IikgJT4lIGNsZWFuX2Z1bihrZXkgPSBxdWVzdGlvbl9rZXksIGV4X2FkZHN1YiA9IFQsIHNpdGUgPSAidGgiLCBhZ2UgPSAiY2giKQoKIyMgVlQgYWR1bHRzCmRfdnRfYWQgPC0gcmVhZC5jc3YoIi9Vc2Vycy9rd2Vpc21hbi9EZXNrdG9wL1RFTVAvVEVNUF9WQU5VQVRVL2JlZXRsZXNfdmFudWF0dV9hZHVsdHNfdGlkeV8yMDE4LTA1LTA5LmNzdiIpICU+JSBjbGVhbl9mdW4oa2V5ID0gcXVlc3Rpb25fa2V5LCBleF9hZGRzdWIgPSBULCBzaXRlID0gInZ0IiwgYWdlID0gImFkIikKIyMgVlQgY2hpbGRyZW4KZF92dF9jaCA8LSByZWFkLmNzdigiL1VzZXJzL2t3ZWlzbWFuL0Rlc2t0b3AvVEVNUC9URU1QX1ZBTlVBVFUvYmVldGxlc192YW51YXR1X2NoaWxkcmVuX3RpZHlfMjAxOC0wNS0wOS5jc3YiKSAlPiUgY2xlYW5fZnVuKGtleSA9IHF1ZXN0aW9uX2tleSwgZXhfYWRkc3ViID0gVCwgc2l0ZSA9ICJ2dCIsIGFnZSA9ICJjaCIpCmBgYAoKYGBge3J9CmRfYWxsIDwtIGJpbmRfcm93cyhkX3VzX2FkICU+JSByb3duYW1lc190b19jb2x1bW4oInN1YmlkIiksIAogICAgICAgICAgICAgICAgICAgZF91c19jaCAlPiUgcm93bmFtZXNfdG9fY29sdW1uKCJzdWJpZCIpLAogICAgICAgICAgICAgICAgICAgZF9naF9hZCAlPiUgcm93bmFtZXNfdG9fY29sdW1uKCJzdWJpZCIpLCAKICAgICAgICAgICAgICAgICAgIGRfZ2hfY2hfZmFudGUgJT4lIHJvd25hbWVzX3RvX2NvbHVtbigic3ViaWQiKSwKICAgICAgICAgICAgICAgICAgIGRfdGhfYWQgJT4lIHJvd25hbWVzX3RvX2NvbHVtbigic3ViaWQiKSwgCiAgICAgICAgICAgICAgICAgICBkX3RoX2NoICU+JSByb3duYW1lc190b19jb2x1bW4oInN1YmlkIiksCiAgICAgICAgICAgICAgICAgICBkX3Z0X2FkICU+JSByb3duYW1lc190b19jb2x1bW4oInN1YmlkIiksIAogICAgICAgICAgICAgICAgICAgZF92dF9jaCAlPiUgcm93bmFtZXNfdG9fY29sdW1uKCJzdWJpZCIpKSAlPiUKICBjb2x1bW5fdG9fcm93bmFtZXMoInN1YmlkIikKYGBgCgojIFNoYXJlZCBjb25jZXB0dWFsIHN0cnVjdHVyZQoKUG9vbGluZyBhbGwgcGFydGljaXBhbnRzIGZyb20gYWxsIHNpdGVzIHRvZ2V0aGVyIGludG8gYSBjb21tb24gZmFjdG9yIHN0cnVjdHVyZS4KCiMjIFBhcmFsbGVsIGFuYWx5c2lzCgojIyMgSG93IG1hbnkgZmFjdG9ycyB0byByZXRhaW4/CgpgYGB7cn0KcmV0ZW5fYWxsX1BBIDwtIGZhLnBhcmFsbGVsKGRfYWxsLCBwbG90ID0gRik7IHJldGVuX2FsbF9QQQpyZXRlbl9hbGxfcGFyIDwtIHJldGVuX2FsbF9QQSRuZmFjdApgYGAKCiMjIyBXaGF0IGFyZSB0aGVzZSBmYWN0b3JzPwoKYGBge3J9CmVmYV9hbGxfcGFyIDwtIGZhKGRfYWxsLCBuZmFjdG9ycyA9IHJldGVuX2FsbF9wYXIsIHJvdGF0ZSA9ICJ2YXJpbWF4IiwKICAgICAgICAgICAgICAgICAgc2NvcmVzID0gInRlbkJlcmdlIiwgaW1wdXRlID0gIm1lZGlhbiIpCgplZmFfYWxsX3Bhcl9mYWN0b3JuYW1lcyA8LSBjKCJbb3RoZXJdIiwgIkJPRElMWSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTT0NJQUwtRU1PVElPTkFMIiwgIkNPR05JVElWRSIpCmVmYV9hbGxfcGFyX2ZhY3Rvcm5hbWVzX3Nob3J0IDwtIGMoIltvdGhlcl0iLCAiQk9ELiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTT0MuLUVNTy4iLCAiQ09HLiIpCmBgYAoKYGBge3IsIGZpZy53aWR0aCA9IDQuMiwgZmlnLmFzcCA9IDAuN30KaGVhdG1hcF9mdW4oZWZhX2FsbF9wYXIsIGZhY3Rvcl9uYW1lcyA9IGVmYV9hbGxfcGFyX2ZhY3Rvcm5hbWVzKSArCiAgbGFicyh0aXRsZSA9ICJGYWN0b3IgbG9hZGluZ3MgKGRhdGEgcG9vbGVkIGFjcm9zcyBhbGwgc2FtcGxlcykiKQpgYGAKCiMjIyBXaGljaCBjYXBhY2l0aWVzIGFyZSBhdHRyaWJ1dGVkIHRvIHdoaWNoIHRhcmdldHM/CgojIyMjIEZhY3RvciBzY29yZXMKCmBgYHtyLCBmaWcud2lkdGggPSA1LCBmaWcuYXNwID0gMC44fQpzY29yZXNwbG90X2Z1bihlZmFfYWxsX3BhciwgdGFyZ2V0ID0gImFsbCIsCiAgICAgICAgICAgICAgIGZhY3Rvcl9uYW1lcyA9IGVmYV9hbGxfcGFyX2ZhY3Rvcm5hbWVzKSArIAogIGxhYnModGl0bGUgPSAiRmFjdG9yIHNjb3JlcyAoYnkgc2FtcGxlLCBmYWN0b3IsIGFuZCB0YXJnZXQgZW50aXR5KSIsCiAgICAgICBzdWJ0aXRsZSA9ICJBbGwgdGFyZ2V0cyIpCmBgYAoKYGBge3IsIGZpZy53aWR0aCA9IDMuNSwgZmlnLmFzcCA9IDAuOH0Kc2NvcmVzcGxvdF9mdW4oZWZhX2FsbF9wYXIsIHRhcmdldCA9IGMoImdob3N0cyIsICJHb2QiLCAiY2hpbGRyZW4iKSwKICAgICAgICAgICAgICAgZmFjdG9yX25hbWVzID0gZWZhX2FsbF9wYXJfZmFjdG9ybmFtZXNfc2hvcnQpICsgCiAgbGFicyh0aXRsZSA9ICJGYWN0b3Igc2NvcmVzIChieSBzYW1wbGUsIGZhY3RvciwgYW5kIHRhcmdldCBlbnRpdHkpIiwKICAgICAgIHN1YnRpdGxlID0gIkh1bWFuIGFuZCAnc3VwZXJuYXR1cmFsJyB0YXJnZXRzIG9ubHkiKQpgYGAKCmBgYHtyLCBmaWcud2lkdGggPSA1LCBmaWcuYXNwID0gMX0KaXRlbXNwbG90X2Z1bihlZmFfYWxsX3BhciwgdGFyZ2V0ID0gYygiZ2hvc3RzIiwgIkdvZCIsICJjaGlsZHJlbiIpKSArCiAgbGFicyh0aXRsZSA9ICJQYXJhbGxlbCBBbmFseXNpcyIpCmBgYAoKIyMjIyBTdW1tYXJ5IHNjb3JlcwoKYGBge3J9CmZhY3RvcnNfcGFyIDwtIGVmYV9hbGxfcGFyJGxvYWRpbmdzW10gJT4lCiAgZGF0YS5mcmFtZSgpICU+JQogIHJvd25hbWVzX3RvX2NvbHVtbigiY2FwYWNpdHkiKSAlPiUKICBnYXRoZXIoZmFjdG9yLCBsb2FkaW5nLCAtY2FwYWNpdHkpICU+JQogIGdyb3VwX2J5KGNhcGFjaXR5KSAlPiUKICB0b3BfbigxLCBsb2FkaW5nKSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgYXJyYW5nZShmYWN0b3IsIGRlc2MobG9hZGluZykpICU+JQogIG11dGF0ZShvcmRlciA9IDE6bnJvdyguKSwKICAgICAgICAgZmFjdG9yID0gZmFjdG9yKGZhY3RvciwKICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IHBhc3RlMCgiTVIiLCAxOmVmYV9hbGxfcGFyJGZhY3RvcnMpLAogICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gZWZhX2FsbF9wYXJfZmFjdG9ybmFtZXMpLAogICAgICAgICBmYWN0b3IgPSBmYWN0b3IoYXMuY2hhcmFjdGVyKGZhY3RvcikpKQoKIyBmYWN0b3JzX3Bhcl9ob3dtYW55IDwtIGZhY3RvcnNfcGFyICU+JQojICAgY291bnQoZmFjdG9yKQojIGZhY3RvcnNfcGFyX2hvd21hbnkgPC0gbWluKGZhY3RvcnNfcGFyX2hvd21hbnkkbikKCmZhY3RvcnNfcGFyX2hvd21hbnkgPC0gNgoKZmFjdG9yc19wYXJfY3VsbGVkIDwtIGZhY3RvcnNfcGFyICU+JQogIGdyb3VwX2J5KGZhY3RvcikgJT4lCiAgdG9wX24oZmFjdG9yc19wYXJfaG93bWFueSwgbG9hZGluZykgJT4lCiAgdW5ncm91cCgpICU+JQogIGFycmFuZ2UoZmFjdG9yLCBkZXNjKGxvYWRpbmcpKSAlPiUKICBtdXRhdGUob3JkZXIgPSAxOm5yb3coLikpCgpzY29yZXNfcGFyX3ByZWxpbSA8LSBkX2FsbCAlPiUKICByb3duYW1lc190b19jb2x1bW4oInNpdGVfYWdlX3N1YmlkX3RhcmdldF9lbnRpdHkiKSAlPiUKICBnYXRoZXIoY2FwYWNpdHksIHJlc3BvbnNlLCAtc2l0ZV9hZ2Vfc3ViaWRfdGFyZ2V0X2VudGl0eSkgJT4lCiAgbXV0YXRlKHNpdGUgPSBnc3ViKCJfLiokIiwgIiIsIHNpdGVfYWdlX3N1YmlkX3RhcmdldF9lbnRpdHkpLAogICAgICAgICBhZ2UgPSBnc3ViKCJfLiokIiwgIiIsIGdzdWIoIl4uLl8iLCAiIiwgc2l0ZV9hZ2Vfc3ViaWRfdGFyZ2V0X2VudGl0eSkpLAogICAgICAgICBzdWJpZCA9IGdzdWIoIl90YXJnZXQuKiQiLCAiIiwgc2l0ZV9hZ2Vfc3ViaWRfdGFyZ2V0X2VudGl0eSksCiAgICAgICAgIHRhcmdldCA9IGdzdWIoIl4uKnRhcmdldF8iLCAiIiwgc2l0ZV9hZ2Vfc3ViaWRfdGFyZ2V0X2VudGl0eSkpICU+JQogIG11dGF0ZSh0YXJnZXQgPSBjYXNlX3doZW4odGFyZ2V0ID09ICJwaWdzIiB+IE5BX2NoYXJhY3Rlcl8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXQgPT0gIk5BIiB+IE5BX2NoYXJhY3Rlcl8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXQgPT0gImNyaWNrZXRzIiB+ICJiZWV0bGVzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSVUUgfiB0YXJnZXQpKSAlPiUKICBtdXRhdGUoc2l0ZSA9IGZhY3RvcihzaXRlLCBsZXZlbHMgPSBjKCJ1cyIsICJnaCIsICJ0aCIsICJjaCIsICJ2dCIpLAogICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIlVTIiwgIkdoYW5hIiwgIlRoYWlsYW5kIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ2hpbmEiLCAiVmFudWF0dSIpKSwKICAgICAgICAgYWdlID0gZmFjdG9yKGFnZSwgbGV2ZWxzID0gYygiYWQiLCAiY2giKSwKICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoImFkdWx0cyIsICJjaGlsZHJlbiIpKSwKICAgICAgICAgdGFyZ2V0ID0gZmFjdG9yKHRhcmdldCwKICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoInJvY2tzIiwgImZsb3dlcnMiLCAiY2VsbCBwaG9uZXMiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImJlZXRsZXMiLCAiY2hpY2tlbnMiLCAibWljZSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZG9ncyIsICJjaGlsZHJlbiIsICJnaG9zdHMiLCAiR29kIikpKSAlPiUKICBzZWxlY3QoLXNpdGVfYWdlX3N1YmlkX3RhcmdldF9lbnRpdHkpICU+JQogIGZ1bGxfam9pbihmYWN0b3JzX3Bhcl9jdWxsZWQpICU+JQogICMgZnVsbF9qb2luKGZhY3RvcnNfcGFyKSAlPiUKICBmaWx0ZXIoIWlzLm5hKHRhcmdldCksICFpcy5uYShmYWN0b3IpKSAlPiUKICBkaXN0aW5jdCgpCgpzY29yZXNfcGFyIDwtIHNjb3Jlc19wYXJfcHJlbGltICU+JQogIGdyb3VwX2J5KHNpdGUsIGFnZSwgc3ViaWQsIHRhcmdldCwgZmFjdG9yKSAlPiUKICBzdW1tYXJpc2Uoc2NvcmUgPSBtZWFuKHJlc3BvbnNlLCBuYS5ybSA9IFQpKSAlPiUKICB1bmdyb3VwKCkKCnNjb3Jlc19wYXJfbWIgPC0gc2NvcmVzX3BhciAlPiUgCiAgZ3JvdXBfYnkoc2l0ZSwgYWdlLCB0YXJnZXQsIGZhY3RvcikgJT4lCiAgbXVsdGlfYm9vdF9zdGFuZGFyZChjb2wgPSAic2NvcmUiLCBuYS5ybSA9IFQpICU+JQogIHVuZ3JvdXAoKQpgYGAKCmBgYHtyfQojIGNhbGN1bGF0ZSByZWxpYWJpbGl0eQpzY29yZXNfcGFyX3ByZWxpbV93aWRlIDwtIHNjb3Jlc19wYXJfcHJlbGltICU+JQogIGZ1bGxfam9pbihmYWN0b3JzX3Bhcl9jdWxsZWQpICU+JQogIGZpbHRlcighaXMubmEoZmFjdG9yKSwgIWlzLm5hKHN1YmlkKSkgJT4lIAogIGFycmFuZ2UoZmFjdG9yLCBkZXNjKGxvYWRpbmcpKSAlPiUKICBzZWxlY3Qoc3ViaWQsIGNhcGFjaXR5LCByZXNwb25zZSkgJT4lCiAgc3ByZWFkKGNhcGFjaXR5LCByZXNwb25zZSkgJT4lCiAgc2VsZWN0KHN1YmlkLCBmYWN0b3JzX3Bhcl9jdWxsZWQkY2FwYWNpdHkpICU+JQogIGNvbHVtbl90b19yb3duYW1lcygic3ViaWQiKQoKIyBCT0RJTFkKcGFzdGUobmFtZXMoc2NvcmVzX3Bhcl9wcmVsaW1fd2lkZVsxOjZdKSwgY29sbGFwc2UgPSAiLCAiKQphbHBoYShzY29yZXNfcGFyX3ByZWxpbV93aWRlWzE6Nl0pJHRvdGFsCgojICJDT0dOSVRJVkUiCnBhc3RlKG5hbWVzKHNjb3Jlc19wYXJfcHJlbGltX3dpZGVbNzoxMl0pLCBjb2xsYXBzZSA9ICIsICIpCmFscGhhKHNjb3Jlc19wYXJfcHJlbGltX3dpZGVbNzoxMl0pJHRvdGFsCgojICJTT0NJQUwtRU1PVElPTkFMIgpwYXN0ZShuYW1lcyhzY29yZXNfcGFyX3ByZWxpbV93aWRlWzEzOjE4XSksIGNvbGxhcHNlID0gIiwgIikKYWxwaGEoc2NvcmVzX3Bhcl9wcmVsaW1fd2lkZVsxMzoxOF0pJHRvdGFsCmBgYAoKCmBgYHtyLCBmaWcud2lkdGggPSA3LCBmaWcuYXNwID0gMC42fQpnZ3Bsb3Qoc2NvcmVzX3BhciwgYWVzKHggPSB0YXJnZXQsIHkgPSBzY29yZSwgY29sb3IgPSBmYWN0b3IpKSArCiAgZmFjZXRfZ3JpZChjb2xzID0gdmFycyhzaXRlLCBhZ2UpLCByb3dzID0gdmFycyhmYWN0b3IpKSArCiAgZ2VvbV9qaXR0ZXIoaGVpZ2h0ID0gMC4wMiwgd2lkdGggPSAwLjIsIGFscGhhID0gMC4yLCBzaG93LmxlZ2VuZCA9IEYpICsKICBnZW9tX3BvaW50cmFuZ2UoZGF0YSA9IHNjb3Jlc19wYXJfbWIsCiAgICAgICAgICAgICAgICAgIGFlcyh5ID0gbWVhbiwgeW1pbiA9IGNpX2xvd2VyLCB5bWF4ID0gY2lfdXBwZXIpLAogICAgICAgICAgICAgICAgICBmYXR0ZW4gPSAyLCBjb2xvciA9ICJibGFjayIpICsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZSA9ICJTZXQxIikgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSwgdmp1c3QgPSAxKSkKYGBgCgpgYGB7ciwgZmlnLndpZHRoID0gMy41LCBmaWcuYXNwID0gMC42fQpnZ3Bsb3Qoc2NvcmVzX3BhciAlPiUKICAgICAgICAgbXV0YXRlKGZhY3Rvcl9zaG9ydCA9IHJlY29kZV9mYWN0b3IoCiAgICAgICAgICAgZmFjdG9yLAogICAgICAgICAgICJCT0RJTFkiID0gIkJPRC4iLAogICAgICAgICAgICJDT0dOSVRJVkUiID0gIkNPRy4iLAogICAgICAgICAgICJTT0NJQUwtRU1PVElPTkFMIiA9ICJTT0MuLUVNTy4iKSkgJT4lCiAgICAgICAgIGZpbHRlcih0YXJnZXQgJWluJSBjKCJjaGlsZHJlbiIsICJnaG9zdHMiLCAiR29kIikpLCAKICAgICAgIGFlcyh4ID0gdGFyZ2V0LCB5ID0gc2NvcmUsIGNvbG9yID0gZmFjdG9yX3Nob3J0KSkgKwogIGZhY2V0X2dyaWQoY29scyA9IHZhcnMoc2l0ZSwgYWdlKSwgcm93cyA9IHZhcnMoZmFjdG9yX3Nob3J0KSkgKwogIGdlb21faml0dGVyKGhlaWdodCA9IDAuMDIsIHdpZHRoID0gMC4yLCBhbHBoYSA9IDAuMjUsIHNob3cubGVnZW5kID0gRikgKwogIGdlb21fcG9pbnRyYW5nZShkYXRhID0gc2NvcmVzX3Bhcl9tYiAlPiUKICAgICAgICAgICAgICAgICAgICBtdXRhdGUoZmFjdG9yX3Nob3J0ID0gcmVjb2RlX2ZhY3RvcigKICAgICAgICAgICAgICAgICAgICAgIGZhY3RvciwKICAgICAgICAgICAgICAgICAgICAgICJCT0RJTFkiID0gIkJPRC4iLAogICAgICAgICAgICAgICAgICAgICAgIkNPR05JVElWRSIgPSAiQ09HLiIsCiAgICAgICAgICAgICAgICAgICAgICAiU09DSUFMLUVNT1RJT05BTCIgPSAiU09DLi1FTU8uIikpICU+JQogICAgICAgICAgICAgICAgICAgIGZpbHRlcih0YXJnZXQgJWluJSBjKCJjaGlsZHJlbiIsICJnaG9zdHMiLCAiR29kIikpLAogICAgICAgICAgICAgICAgICBhZXMoeSA9IG1lYW4sIHltaW4gPSBjaV9sb3dlciwgeW1heCA9IGNpX3VwcGVyKSwKICAgICAgICAgICAgICAgICAgZmF0dGVuID0gMiwgY29sb3IgPSAiYmxhY2siKSArCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSAiU2V0MSIpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEsIHZqdXN0ID0gMSkpCmBgYAoKCiMjIE1pbmltaXppbmcgQklDCgojIyMgSG93IG1hbnkgZmFjdG9ycyB0byByZXRhaW4/CgpgYGB7cn0KcmV0ZW5fYWxsX0JJQyA8LSBWU1MoZF9hbGwsIHBsb3QgPSBGKTsgcmV0ZW5fYWxsX0JJQwpyZXRlbl9hbGxfYmljIDwtIGRhdGEuZnJhbWUocmV0ZW5fYWxsX0JJQyR2c3Muc3RhdHMgJT4lIHJvd25hbWVzX3RvX2NvbHVtbigibmZhY3QiKSAlPiUgdG9wX24oLTEsIEJJQykpJG5mYWN0ICU+JSBhcy5udW1lcmljKCkKYGBgCgojIyBQcmVzZXQgY3JpdGVyaWEKCiMjIyBIb3cgbWFueSBmYWN0b3JzIHRvIHJldGFpbj8KCmBgYHtyfQpyZXRlbl9hbGxfayA8LSByZXRlbl9mdW4oZF9hbGwsIHJvdF90eXBlID0gInZhcmltYXgiKTsgcmV0ZW5fYWxsX2sKYGBgCgojIyMgV2hhdCBhcmUgdGhlc2UgZmFjdG9ycz8KCmBgYHtyfQplZmFfYWxsX2sgPC0gZmEoZF9hbGwsIG5mYWN0b3JzID0gcmV0ZW5fYWxsX2ssIHJvdGF0ZSA9ICJ2YXJpbWF4IiwKICAgICAgICAgICAgICAgIHNjb3JlcyA9ICJ0ZW5CZXJnZSIsIGltcHV0ZSA9ICJtZWRpYW4iKQpgYGAKCmBgYHtyLCBmaWcud2lkdGggPSAzLCBmaWcuYXNwID0gMn0KaGVhdG1hcF9mdW4oZWZhX2FsbF9rKSArIAogIGxhYnModGl0bGUgPSAiUHJlc2V0IGNyaXRlcmlhIChXZWlzbWFuIGV0IGFsLiwgMjAxNykiKQpgYGAKCiMjIyBXaGljaCBjYXBhY2l0aWVzIGFyZSBhdHRyaWJ1dGVkIHRvIHdoaWNoIHRhcmdldHM/CgpgYGB7ciwgZmlnLndpZHRoID0gNiwgZmlnLmFzcCA9IDAuOH0Kc2NvcmVzcGxvdF9mdW4oZWZhX2FsbF9rLCB0YXJnZXQgPSAiYWxsIikgKyAKICBsYWJzKHRpdGxlID0gIlByZXNldCBjcml0ZXJpYSAoV2Vpc21hbiBldCBhbC4sIDIwMTcpIikKYGBgCgpgYGB7ciwgZmlnLndpZHRoID0gMywgZmlnLmFzcCA9IDEuNX0Kc2NvcmVzcGxvdF9mdW4oZWZhX2FsbF9rLCB0YXJnZXQgPSBjKCJnaG9zdHMiLCAiR29kIiwgImNoaWxkcmVuIikpICsgCiAgbGFicyh0aXRsZSA9ICJQcmVzZXQgY3JpdGVyaWEgKFdlaXNtYW4gZXQgYWwuLCAyMDE3KSIpCmBgYAoKYGBge3IsIGZpZy53aWR0aCA9IDUsIGZpZy5hc3AgPSAxfQppdGVtc3Bsb3RfZnVuKGVmYV9hbGxfaywgdGFyZ2V0ID0gYygiZ2hvc3RzIiwgIkdvZCIsICJjaGlsZHJlbiIpKSArIAogIGxhYnModGl0bGUgPSAiUHJlc2V0IGNyaXRlcmlhIChXZWlzbWFuIGV0IGFsLiwgMjAxNykiKQpgYGAKCgojIyAzIGZhY3RvcnMKCiMjIyBXaGF0IGFyZSB0aGVzZSBmYWN0b3JzPwoKYGBge3J9CmVmYV9hbGxfMyA8LSBmYShkX2FsbCwgbmZhY3RvcnMgPSAzLCByb3RhdGUgPSAidmFyaW1heCIsCiAgICAgICAgICAgICAgICBzY29yZXMgPSAidGVuQmVyZ2UiLCBpbXB1dGUgPSAibWVkaWFuIikKZWZhX2FsbF8zX2ZhY3Rvcm5hbWVzIDwtIGMoIkJPRElMWSIsICJDT0dOSVRJVkUiLCAiU09DSUFMLUVNT1RJT05BTCIpCmVmYV9hbGxfM19mYWN0b3JuYW1lc19zaG9ydCA8LSBjKCJCT0QuIiwgIkNPRy4iLCAiU09DLi1FTU8uIikKYGBgCgpgYGB7ciwgZmlnLndpZHRoID0gNCwgZmlnLmFzcCA9IDAuNn0KaGVhdG1hcF9mdW4oZWZhX2FsbF8zLCBmYWN0b3JfbmFtZXMgPSBlZmFfYWxsXzNfZmFjdG9ybmFtZXMpICsgCiAgbGFicyh4ID0gIlNoYXJlZCBjb25jcGV0dWFsIHN0cnVjdHVyZSIpICsKICB0aGVtZShheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwKSkKIyBsYWJzKHRpdGxlID0gIlByZXNldCBjcml0ZXJpYSAoV2Vpc21hbiBldCBhbC4sIDIwMTcpIikKYGBgCgojIyMgV2hpY2ggY2FwYWNpdGllcyBhcmUgYXR0cmlidXRlZCB0byB3aGljaCB0YXJnZXRzPwoKYGBge3IsIGZpZy53aWR0aCA9IDYsIGZpZy5hc3AgPSAwLjY3fQpzY29yZXNwbG90X2Z1bihlZmFfYWxsXzMsIHRhcmdldCA9ICJhbGwiLCBoaWdobGlnaHQgPSAic3VwZXJuYXR1cmFsIiwKICAgICAgICAgICAgICAgZmFjdG9yX25hbWVzID0gZWZhX2FsbF8zX2ZhY3Rvcm5hbWVzKSArCiAgIyBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCIjZTQxYTFjIiwgIiM0ZGFmNGEiLCAiIzM3N2ViOCIpKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgaGp1c3QgPSAxLCB2anVzdCA9IDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSBjKHJlcCgiYmxhY2siLCA4KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwKCIjOTg0ZWEzIiwgMikpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhY2UgPSBjKHJlcCgicGxhaW4iLCA4KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXAoImJvbGQiLCAyKSkpKQpgYGAKCmBgYHtyLCBmaWcud2lkdGggPSAzLCBmaWcuYXNwID0gMS41fQpzY29yZXNwbG90X2Z1bihlZmFfYWxsXzMsIHRhcmdldCA9IGMoImdob3N0cyIsICJHb2QiLCAiY2hpbGRyZW4iKSwgCiAgICAgICAgICAgICAgIGZhY3Rvcl9uYW1lcyA9IGVmYV9hbGxfM19mYWN0b3JuYW1lc19zaG9ydCkgKyAKICBsYWJzKHRpdGxlID0gIlByZXNldCBjcml0ZXJpYSAoV2Vpc21hbiBldCBhbC4sIDIwMTcpIikKYGBgCgpgYGB7ciwgZmlnLndpZHRoID0gNSwgZmlnLmFzcCA9IDF9Cml0ZW1zcGxvdF9mdW4oZWZhX2FsbF8zLCB0YXJnZXQgPSBjKCJnaG9zdHMiLCAiR29kIiwgImNoaWxkcmVuIiksCiAgICAgICAgICAgICAgZmFjdG9yX25hbWVzID0gZWZhX2FsbF8zX2ZhY3Rvcm5hbWVzKSArIAogIGxhYnModGl0bGUgPSAiUHJlc2V0IGNyaXRlcmlhIChXZWlzbWFuIGV0IGFsLiwgMjAxNykiKQpgYGAKCgojIENvbXBhcmluZyBjb25jZXB0dWFsIHN0cnVjdHVyZXMKCiMjIDQgZmFjdG9ycwoKV2UnbGwgZXh0cmFjdCA0IGZhY3RvcnMgZnJvbSBhbGwgc2FtcGxlcywgdG8ga2VlcCB0aGluZ3Mgc2ltcGxlLgoKYGBge3J9CmVmYV91c19hZF80IDwtIGZhKGRfdXNfYWQsIG5mYWN0b3JzID0gNCwgcm90YXRlID0gInZhcmltYXgiKQplZmFfdXNfY2hfNCA8LSBmYShkX3VzX2NoLCBuZmFjdG9ycyA9IDQsIHJvdGF0ZSA9ICJ2YXJpbWF4IikKZWZhX2doX2FkXzQgPC0gZmEoZF9naF9hZCwgbmZhY3RvcnMgPSA0LCByb3RhdGUgPSAidmFyaW1heCIpCmVmYV9naF9jaF80IDwtIGZhKGRfZ2hfY2hfZmFudGUsIG5mYWN0b3JzID0gNCwgcm90YXRlID0gInZhcmltYXgiKQplZmFfdGhfYWRfNCA8LSBmYShkX3RoX2FkLCBuZmFjdG9ycyA9IDQsIHJvdGF0ZSA9ICJ2YXJpbWF4IikKZWZhX3RoX2NoXzQgPC0gZmEoZF90aF9jaCwgbmZhY3RvcnMgPSA0LCByb3RhdGUgPSAidmFyaW1heCIpCmVmYV92dF9hZF80IDwtIGZhKGRfdnRfYWQsIG5mYWN0b3JzID0gNCwgcm90YXRlID0gInZhcmltYXgiKQplZmFfdnRfY2hfNCA8LSBmYShkX3Z0X2NoLCBuZmFjdG9ycyA9IDQsIHJvdGF0ZSA9ICJ2YXJpbWF4IikKYGBgCgpgYGB7cn0KcGxvdF91c19hZF80IDwtIGhlYXRtYXBfZnVuKGVmYV91c19hZF80KSArIAogIGd1aWRlcyhmaWxsID0gIm5vbmUiKSArIAogIGxhYnMoeCA9ICJVUzogYWR1bHRzIikgKwogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDApKQoKcGxvdF91c19jaF80IDwtIGhlYXRtYXBfZnVuKGVmYV91c19jaF80KSArIAogIGd1aWRlcyhmaWxsID0gIm5vbmUiKSArIAogIGxhYnMoeCA9ICJVUzogY2hpbGRyZW4iKSArCiAgdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMCkpCgpwbG90X2doX2FkXzQgPC0gaGVhdG1hcF9mdW4oZWZhX2doX2FkXzQpICsgCiAgZ3VpZGVzKGZpbGwgPSAibm9uZSIpICsgCiAgbGFicyh4ID0gIkdoYW5hOiBhZHVsdHMiKSArCiAgdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMCkpCgpwbG90X2doX2NoXzQgPC0gaGVhdG1hcF9mdW4oZWZhX2doX2NoXzQpICsgCiAgZ3VpZGVzKGZpbGwgPSAibm9uZSIpICsgCiAgbGFicyh4ID0gIkdoYW5hOiBjaGlsZHJlbiIpICsKICB0aGVtZShheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwKSkKCnBsb3RfdGhfYWRfNCA8LSBoZWF0bWFwX2Z1bihlZmFfdGhfYWRfNCkgKyAKICBndWlkZXMoZmlsbCA9ICJub25lIikgKyAKICBsYWJzKHggPSAiVGhhaWxhbmQ6IGFkdWx0cyIpICsKICB0aGVtZShheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwKSkKCnBsb3RfdGhfY2hfNCA8LSBoZWF0bWFwX2Z1bihlZmFfdGhfY2hfNCkgKyAKICBndWlkZXMoZmlsbCA9ICJub25lIikgKyAKICBsYWJzKHggPSAiVGhhaWxhbmQ6IGNoaWxkcmVuIikgKwogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDApKQoKcGxvdF92dF9hZF80IDwtIGhlYXRtYXBfZnVuKGVmYV92dF9hZF80KSArIAogIGd1aWRlcyhmaWxsID0gIm5vbmUiKSArIAogIGxhYnMoeCA9ICJWYW51YXR1OiBhZHVsdHMiKSArCiAgdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMCkpCgpwbG90X3Z0X2NoXzQgPC0gaGVhdG1hcF9mdW4oZWZhX3Z0X2NoXzQpICsgCiAgZ3VpZGVzKGZpbGwgPSAibm9uZSIpICsgCiAgbGFicyh4ID0gIlZhbnVhdHU6IGNoaWxkcmVuIikgKwogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDApKQpgYGAKCmBgYHtyLCBmaWcuYXNwID0gMS41fQpwbG90X2dyaWQocGxvdF91c19hZF80LCBwbG90X3VzX2NoXzQsIAogICAgICAgICAgcGxvdF9naF9hZF80LCBwbG90X2doX2NoXzQsIAogICAgICAgICAgcGxvdF90aF9hZF80LCBwbG90X3RoX2NoXzQsIAogICAgICAgICAgcGxvdF92dF9hZF80LCBwbG90X3Z0X2NoXzQsIAogICAgICAgICAgbmNvbCA9IDIsIGxhYmVscyA9ICJBVVRPIikKYGBgCgojIyAzIGZhY3RvcnMKCldlJ2xsIGV4dHJhY3QgMyBmYWN0b3JzIGZyb20gYWxsIHNhbXBsZXMsIHRvIGtlZXAgdGhpbmdzIHNpbXBsZS4KCmBgYHtyfQplZmFfdXNfYWRfMyA8LSBmYShkX3VzX2FkLCBuZmFjdG9ycyA9IDMsIHJvdGF0ZSA9ICJ2YXJpbWF4IikKZWZhX3VzX2NoXzMgPC0gZmEoZF91c19jaCwgbmZhY3RvcnMgPSAzLCByb3RhdGUgPSAidmFyaW1heCIpCmVmYV9naF9hZF8zIDwtIGZhKGRfZ2hfYWQsIG5mYWN0b3JzID0gMywgcm90YXRlID0gInZhcmltYXgiKQplZmFfZ2hfY2hfMyA8LSBmYShkX2doX2NoX2ZhbnRlLCBuZmFjdG9ycyA9IDMsIHJvdGF0ZSA9ICJ2YXJpbWF4IikKZWZhX3RoX2FkXzMgPC0gZmEoZF90aF9hZCwgbmZhY3RvcnMgPSAzLCByb3RhdGUgPSAidmFyaW1heCIpCmVmYV90aF9jaF8zIDwtIGZhKGRfdGhfY2gsIG5mYWN0b3JzID0gMywgcm90YXRlID0gInZhcmltYXgiKQplZmFfdnRfYWRfMyA8LSBmYShkX3Z0X2FkLCBuZmFjdG9ycyA9IDMsIHJvdGF0ZSA9ICJ2YXJpbWF4IikKZWZhX3Z0X2NoXzMgPC0gZmEoZF92dF9jaCwgbmZhY3RvcnMgPSAzLCByb3RhdGUgPSAidmFyaW1heCIpCmBgYAoKYGBge3J9CnBsb3RfdXNfYWRfMyA8LSBoZWF0bWFwX2Z1bihlZmFfdXNfYWRfMykgKyAKICBndWlkZXMoZmlsbCA9ICJub25lIikgKyAKICBsYWJzKHggPSAiVVM6IGFkdWx0cyIpICsKICB0aGVtZShheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwKSkKCnBsb3RfdXNfY2hfMyA8LSBoZWF0bWFwX2Z1bihlZmFfdXNfY2hfMykgKyAKICBndWlkZXMoZmlsbCA9ICJub25lIikgKyAKICBsYWJzKHggPSAiVVM6IGNoaWxkcmVuIikgKwogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDApKQoKcGxvdF9naF9hZF8zIDwtIGhlYXRtYXBfZnVuKGVmYV9naF9hZF8zKSArIAogIGd1aWRlcyhmaWxsID0gIm5vbmUiKSArIAogIGxhYnMoeCA9ICJHaGFuYTogYWR1bHRzIikgKwogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDApKQoKcGxvdF9naF9jaF8zIDwtIGhlYXRtYXBfZnVuKGVmYV9naF9jaF8zKSArIAogIGd1aWRlcyhmaWxsID0gIm5vbmUiKSArIAogIGxhYnMoeCA9ICJHaGFuYTogY2hpbGRyZW4iKSArCiAgdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMCkpCgpwbG90X3RoX2FkXzMgPC0gaGVhdG1hcF9mdW4oZWZhX3RoX2FkXzMpICsgCiAgZ3VpZGVzKGZpbGwgPSAibm9uZSIpICsgCiAgbGFicyh4ID0gIlRoYWlsYW5kOiBhZHVsdHMiKSArCiAgdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMCkpCgpwbG90X3RoX2NoXzMgPC0gaGVhdG1hcF9mdW4oZWZhX3RoX2NoXzMpICsgCiAgZ3VpZGVzKGZpbGwgPSAibm9uZSIpICsgCiAgbGFicyh4ID0gIlRoYWlsYW5kOiBjaGlsZHJlbiIpICsKICB0aGVtZShheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwKSkKCnBsb3RfdnRfYWRfMyA8LSBoZWF0bWFwX2Z1bihlZmFfdnRfYWRfMykgKyAKICBndWlkZXMoZmlsbCA9ICJub25lIikgKyAKICBsYWJzKHggPSAiVmFudWF0dTogYWR1bHRzIikgKwogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDApKQoKcGxvdF92dF9jaF8zIDwtIGhlYXRtYXBfZnVuKGVmYV92dF9jaF8zKSArIAogIGd1aWRlcyhmaWxsID0gIm5vbmUiKSArIAogIGxhYnMoeCA9ICJWYW51YXR1OiBjaGlsZHJlbiIpICsKICB0aGVtZShheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwKSkKYGBgCgpgYGB7ciwgZmlnLmFzcCA9IDEuNX0KcGxvdF9ncmlkKHBsb3RfdXNfYWRfMywgcGxvdF91c19jaF8zLCAKICAgICAgICAgIHBsb3RfZ2hfYWRfMywgcGxvdF9naF9jaF8zLCAKICAgICAgICAgIHBsb3RfdGhfYWRfMywgcGxvdF90aF9jaF8zLCAKICAgICAgICAgIHBsb3RfdnRfYWRfMywgcGxvdF92dF9jaF8zLCAKICAgICAgICAgIG5jb2wgPSAyLCBsYWJlbHMgPSAiQVVUTyIpCmBgYAoKIyBDb3VudHMKCmBgYHtyfQpwYXN0ZSgiVVMgYWR1bHRzOiIsIG5yb3coZF91c19hZCkpCnBhc3RlKCJVUyBjaGlsZHJlbjoiLCBucm93KGRfdXNfY2gpKQpwYXN0ZSgiR0ggYWR1bHRzOiIsIG5yb3coZF9naF9hZCkpCnBhc3RlKCJHSCBjaGlsZHJlbjoiLCBucm93KGRfZ2hfY2gpKQpwYXN0ZSgiVEggYWR1bHRzOiIsIG5yb3coZF90aF9hZCkpCnBhc3RlKCJUSCBjaGlsZHJlbjoiLCBucm93KGRfdGhfY2gpKQpwYXN0ZSgiVlQgYWR1bHRzOiIsIG5yb3coZF92dF9hZCkpCnBhc3RlKCJWVCBjaGlsZHJlbjoiLCBucm93KGRfdnRfY2gpKQoKcGFzdGUoIk5vbi1VUzoiLCBzdW0obnJvdyhkX2doX2FkKSwgbnJvdyhkX2doX2NoKSwKICAgICAgICAgICAgICAgICAgICAgbnJvdyhkX3RoX2FkKSwgbnJvdyhkX3RoX2NoKSwKICAgICAgICAgICAgICAgICAgICAgbnJvdyhkX3Z0X2FkKSwgbnJvdyhkX3Z0X2NoKSkpCgpwYXN0ZTAoIkFkdWx0czogbiA9ICIsIG1pbihucm93KGRfdXNfYWQpLCBucm93KGRfZ2hfYWQpLCBucm93KGRfdGhfYWQpLCBucm93KGRfdnRfYWQpKSwgIi0iLCBtYXgobnJvdyhkX3VzX2FkKSwgbnJvdyhkX2doX2FkKSwgbnJvdyhkX3RoX2FkKSwgbnJvdyhkX3Z0X2FkKSksICI7IHRvdGFsIE4gPSAiLCAgc3VtKG5yb3coZF91c19hZCksIG5yb3coZF9naF9hZCksIG5yb3coZF90aF9hZCksIG5yb3coZF92dF9hZCkpKQoKcGFzdGUwKCJDaGlsZHJlbjogbiA9ICIsIG1pbihucm93KGRfdXNfY2gpLCBucm93KGRfZ2hfY2gpLCBucm93KGRfdGhfY2gpLCBucm93KGRfdnRfY2gpKSwgIi0iLCBtYXgobnJvdyhkX3VzX2NoKSwgbnJvdyhkX2doX2NoKSwgbnJvdyhkX3RoX2NoKSwgbnJvdyhkX3Z0X2NoKSksICI7IHRvdGFsIE4gPSAiLCAgc3VtKG5yb3coZF91c19jaCksIG5yb3coZF9naF9jaCksIG5yb3coZF90aF9jaCksIG5yb3coZF92dF9jaCkpKQpgYGAKCmBgYHtyfQpkX2FsbCAlPiUKICByb3duYW1lc190b19jb2x1bW4oInNpdGVfYWdlX3N1YmlkX3RhcmdldF9jaGFyYWN0ZXIiKSAlPiUKICBtdXRhdGUoc2l0ZV9hZ2Vfc3ViaWRfdGFyZ2V0X2NoYXJhY3RlciA9IGdzdWIoImNlbGwgcGhvbmVzIiwgImNlbGxwaG9uZXMiLCBzaXRlX2FnZV9zdWJpZF90YXJnZXRfY2hhcmFjdGVyKSkgJT4lCiAgc2VwYXJhdGUoc2l0ZV9hZ2Vfc3ViaWRfdGFyZ2V0X2NoYXJhY3RlciwgaW50byA9IGMoInNpdGUiLCAiYWdlIiwgInN1YmlkIiwgInRhcmdldCIsICJjaGFyYWN0ZXIiKSkgJT4lCiAgY291bnQoc2l0ZSwgYWdlLCBjaGFyYWN0ZXIpICU+JQogIHNwcmVhZChjaGFyYWN0ZXIsIG4pCmBgYAoKYGBge3J9CmRfYWxsICU+JQogIHJvd25hbWVzX3RvX2NvbHVtbigic2l0ZV9hZ2Vfc3ViaWRfdGFyZ2V0X2NoYXJhY3RlciIpICU+JQogIG11dGF0ZShzaXRlX2FnZV9zdWJpZF90YXJnZXRfY2hhcmFjdGVyID0gZ3N1YigiY2VsbCBwaG9uZXMiLCAiY2VsbHBob25lcyIsIHNpdGVfYWdlX3N1YmlkX3RhcmdldF9jaGFyYWN0ZXIpKSAlPiUKICBzZXBhcmF0ZShzaXRlX2FnZV9zdWJpZF90YXJnZXRfY2hhcmFjdGVyLCBpbnRvID0gYygic2l0ZSIsICJhZ2UiLCAic3ViaWQiLCAidGFyZ2V0IiwgImNoYXJhY3RlciIpKSAlPiUKICBmaWx0ZXIoaXMubmEoY2hhcmFjdGVyKSB8IGNoYXJhY3RlciA9PSAiTkEiKQpgYGAKCgoK